package common;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseDaoImpl  extends HibernateDaoSupport implements BaseDao {

	public <T> T get(Class<T> cls, Serializable ID) {
		return this.getHibernateTemplate().get(cls,ID);
	}
	
	public <T> void update(T t) {
		
		 this.getHibernateTemplate().update(t);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findAll(String hql, Object... values) {
		
		return (List<T>) this.getHibernateTemplate().find(hql,values);
	}

	public <T> void delete(T t) {
		this.getHibernateTemplate().delete(t);
		
	}

	public <T> void executeHql(final String hql,final Object... values) {
		this.getHibernateTemplate().execute(new HibernateCallback <T> () {

			public T doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				if(values!=null){
					for (int i = 0; i < values.length; i++) {
						query.setParameter(i, values[i]);
					}
				}
			 query.executeUpdate();
			 return null;
			}
		});
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findAll(final String hql,final int firstResult,final int maxResult,final
			Object... values) {
		return this.getHibernateTemplate().executeFind(new HibernateCallback <List<T>>() {

			public List<T> doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query=session.createQuery(hql);
				if (values != null) {
					for (int i = 0; i < values.length; i++) {
						query.setParameter(i, values[i]);
					}
				}
				query.setFirstResult(firstResult);
				query.setMaxResults(maxResult);
				return query.list();
			}
		});

	}

	public <T> void save(T t) {
		this.getHibernateTemplate().save(t);		
	}

	public <T> T findOneByHql(final String hql,final Object... values) {
		return 	this.getHibernateTemplate().execute(new HibernateCallback<T>() {
			@SuppressWarnings("unchecked")
			public T doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(hql);

				if (values != null) {
					for (int i = 0; i < values.length; i++) {
						query.setParameter(i, values[i]);
					}
				}
				return (T) query.uniqueResult();
			}
		});
	}

	public Long count(final String hql,final Object... values) {
		return this.getHibernateTemplate().execute(
				new HibernateCallback<Long>() {
					public Long doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						if (values != null) {
							for (int i = 0; i < values.length; i++) {
								query.setParameter(i, values[i]);
							}
						}
						return (Long) query.uniqueResult();
					}
				});
	}
	
}
